import 'whatwg-fetch'
import 'custom-event-polyfill'

import type { VueConstructor } from 'vue'
import type { plugin } from 'wujie'
import WujieVue from 'wujie-vue2'

const lifeCycles = {
  beforeLoad: (appWindow: Window) =>
    console.log(`${appWindow.__WUJIE.id} beforeLoad 生命周期`),
  beforeMount: (appWindow: Window) =>
    console.log(`${appWindow.__WUJIE.id} beforeMount 生命周期`),
  afterMount: (appWindow: Window) =>
    console.log(`${appWindow.__WUJIE.id} afterMount 生命周期`),
  beforeUnmount: (appWindow: Window) =>
    console.log(`${appWindow.__WUJIE.id} beforeUnmount 生命周期`),
  afterUnmount: (appWindow: Window) =>
    console.log(`${appWindow.__WUJIE.id} afterUnmount 生命周期`),
  activated: (appWindow: Window) =>
    console.log(`${appWindow.__WUJIE.id} activated 生命周期`),
  deactivated: (appWindow: Window) =>
    console.log(`${appWindow.__WUJIE.id} deactivated 生命周期`),
  loadError: (url: string, e: Error) => console.log(`${url} 加载失败`, e)
}

const plugins = {
  // Vite 需要处理样式加载逻辑，https://github.com/Tencent/wujie/issues/434#issuecomment-1614089196
  fixViteStyle: {
    patchElementHook(element, iframeWindow) {
      if (element.nodeName === 'STYLE') {
        element.insertAdjacentElement = function (_position, ele) {
          iframeWindow.document.head.appendChild(ele)
        }
      }
    }
  } as plugin
}

// 携带登录态credentials必须为include
function credentialsFetch(
  url: RequestInfo | URL,
  options: RequestInit | undefined
) {
  return window.fetch(url, { ...(options || {}), credentials: 'omit' })
}

export function useWujie(app: VueConstructor, router: any) {
  const { setupApp, preloadApp, bus } = WujieVue

  app.use(WujieVue)

  bus.$on('click', (msg: string) => {
    window.alert(msg)
  })

  bus.$on('sub-route-change', (name: string, path: string) => {
    const mainName = `${name}-sub`
    const mainPath = `/${name}-sub${path}`
    const currentName = router.currentRoute.name
    const currentPath = router.currentRoute.path
    if (mainName === currentName && mainPath !== currentPath) {
      router.push({ path: mainPath })
    }
  })

  const degrade =
    window.localStorage.getItem('degrade') === 'true' ||
    !window.Proxy ||
    !window.CustomElementRegistry
  const props = {
    jump: (name: string) => {
      router.push({ name })
    }
  }

  setupApp({
    name: 'vue2',
    url: process.env.VUE_APP_VUE2_ENTRY,
    exec: true,
    props,
    degrade,
    fetch: credentialsFetch,
    ...lifeCycles
  })

  setupApp({
    name: 'vue3',
    url: process.env.VUE_APP_VUE3_ENTRY,
    alive: true,
    exec: true,
    props,
    degrade,
    fetch: credentialsFetch,
    ...lifeCycles
  })

  setupApp({
    name: 'vite-vue2',
    url: process.env.VUE_APP_VITE_VUE2_ENTRY,
    exec: true,
    props,
    degrade,
    plugins: [plugins.fixViteStyle],
    fetch: credentialsFetch,
    ...lifeCycles
  })

  setupApp({
    name: 'vite-vue3',
    url: process.env.VUE_APP_VITE_VUE3_ENTRY,
    alive: true,
    exec: true,
    props,
    degrade,
    plugins: [plugins.fixViteStyle],
    fetch: credentialsFetch,
    ...lifeCycles
  })

  setupApp({
    name: 'rs-vue2',
    url: process.env.VUE_APP_RS_VUE2_ENTRY,
    exec: true,
    props,
    degrade,
    fetch: credentialsFetch,
    ...lifeCycles
  })

  setupApp({
    name: 'rs-vue3',
    url: process.env.VUE_APP_RS_VUE3_ENTRY,
    alive: true,
    exec: true,
    props,
    degrade,
    fetch: credentialsFetch,
    ...lifeCycles
  })

  if (window.localStorage.getItem('preload') !== 'false') {
    // @ts-ignore
    preloadApp({
      name: 'vue2'
    })
    if (window.Proxy) {
      // @ts-ignore
      preloadApp({
        name: 'vue3'
      })
      // @ts-ignore
      preloadApp({
        name: 'vite-vue2'
      })
      // @ts-ignore
      preloadApp({
        name: 'vite-vue3'
      })
      // @ts-ignore
      preloadApp({
        name: 'rs-vue2'
      })
      // @ts-ignore
      preloadApp({
        name: 'rs-vue3'
      })
    }
  }
}
